﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Security.Cryptography;
using System.Text;

public partial class Course_ltiep : System.Web.UI.Page
{
    static string Secret = "secret";

    public string Action
    {
        get
        {
            if (Request.Params["action"] != null)
                return Request.Params["action"];
            return "";
        }
    }

    public string UserID
    {
        get
        {
            if (Request.Params["user_id"] != null)
                return Request.Params["user_id"];
            return "";
        }
    }

    public string OrgID
    {
        get
        {
            if(Request.Params["org_id"] != null)
                return Request.Params["org_id"];
            return "";
        }
    }

    public string FirstName
    {
        get
        {
            if (Request.Params["user_firstname"] != null)
                return Request.Params["user_firstname"];
            return "";
        }
    }

    public string LastName
    {
        get
        {
            if (Request.Params["user_lastname"] != null)
                return Request.Params["user_lastname"];
            return "";
        }
    }

    public string Email
    {
        get
        {
            if (Request.Params["user_email"] != null)
                return Request.Params["user_email"];
            return "";
        }
    }

    public string ToolID
    {
        get
        {
            if (Request.Params["launch_tool_id"] != null)
                return Request.Params["launch_tool_id"];
            return "";
        }
    }

    public string CourseID
    {
        get
        {
            if (Request.Params["courseid"] != null)
                return Request.Params["courseid"];
            return "";
        }
    }

    public string Nonce
    {
        get
        {
            if (Request.Params["sec_nonce"] != null)
                return Request.Params["sec_nonce"];
            return "";
        }
    }

    public string Digest
    {
        get
        {
            if (Request.Params["sec_digest"] != null)
                return Request.Params["sec_digest"];
            return "";
        }
    }

    public string DateStamp
    {
        get
        {
            if (Request.Params["sec_created"] != null)
                return Request.Params["sec_created"];
            return "";
        }
    }

    public string UserRole
    {
        get
        {
            if (Request.Params["user_role"] != null)
                return Request.Params["user_role"];
            return "";
        }
    }

    public string OAuthSignature
    {
        get
        {
            if (Request.Params["oauth_signature"] != null)
                return Request.Params["oauth_signature"];
            return "";
        }
    }

    public string OAuthConsumerKey
    {
        get
        {
            if (Request.Params["oauth_consumer_key"] != null)
                return Request.Params["oauth_consumer_key"];
            return "";
        }
    }

    public string OAuthNonce
    {
        get
        {
            if (Request.Params["oauth_nonce"] != null)
                return Request.Params["oauth_nonce"];
            return "";
        }
    }

    public string OAuthTimestamp
    {
        get
        {
            if (Request.Params["oauth_timestamp"] != null)
                return Request.Params["oauth_timestamp"];
            return "";
        }
    }

    public string OAuthSignatureMethod
    {
        get
        {
            if (Request.Params["oauth_signature_method"] != null)
                return Request.Params["oauth_signature_method"];
            return "";
        }
    }

    public string OAuthVersion
    {
        get
        {
            if (Request.Params["oauth_version"] != null)
                return Request.Params["oauth_version"];
            return "";
        }
    }

    public string OAuthToken
    {
        get
        {
            if (Request.Params["oauth_token"] != null)
                return Request.Params["oauth_token"];
            return "";
        }
    }

    protected void Page_Load(object sender, EventArgs e)
    {
        BasicLTI();
    }

    private void BasicLTI()
    {
        OAuth.OAuthBase ob = new OAuth.OAuthBase();
        List<OAuth.OAuthBase.QueryParameter> QPs = new List<OAuth.OAuthBase.QueryParameter>();
        long Ticks = 0, cTicks = 0;
        long.TryParse(OAuthTimestamp, out Ticks);
        long.TryParse(ob.GenerateTimeStamp(), out cTicks);

        string Signature = "";

        if (OAuthConsumerKey == "")
        {
            Response.Write("Consumer Key Needed");
            return;
        }
        if (OAuthNonce == "")
        {
            Response.Write("Nonce Needed");
            return;
        }
        if (Math.Abs(cTicks - Ticks) > TimeSpan.FromSeconds(10).Ticks)
        {
            Response.Write("Timestamp expired " + ob.GenerateTimeStamp() + " " + Ticks.ToString());
            return;
        }

        foreach (string key in Request.Params)
        {
            if (key.Contains("ASPXANONYMOUS") || key.Contains(".ASPNET"))
                break;
            if (key.ToLower() != "oauth_signature")
            {
                Response.Write(key + "=" + Request.Params[key] + "<br>");
                QPs.Add(new OAuth.OAuthBase.QueryParameter(key, Request.Params[key]));
            }
        }

        string SignatureBase = ob.GenerateSignatureBase(new Uri(Utility.GetSiteRoot().ToLower() + "/" + ResolveClientUrl("~/ltiep.aspx")), QPs);
        Signature = ob.GenerateSignature(SignatureBase, "secret", "");

        Response.Write("<br>" + OAuthSignature + "<br>" + Signature + "<br><br>" + SignatureBase + "<br><br>");

        if (Signature != OAuthSignature)
        {
            Response.Write("Authorization Failed");
            return;
        }

        LMSData.UserController uc = new LMSData.UserController();
        LMSData.UserProfileController upc = new LMSData.UserProfileController();
        LMSData.User usr = uc.FetchByName(UserID);
        if (!usr.IsLoaded)
        {
            System.Web.Security.Membership.CreateUser(UserID, Guid.NewGuid().ToString(), "");
            usr = uc.FetchByName(UserID);
            LMSData.UserProfile up = upc.FetchByUserID(usr.UserID);
            up.UserID = usr.UserID;
            up.FirstName = FirstName;
            up.LastName = LastName;
            up.Save();
        }

        string MirNonce = Guid.NewGuid().ToString();
        Session[MirNonce] = UserID;


        string rsp = "<launchUrl>" + Utility.GetSiteRoot() + "/Course/Nav.aspx?FN=" + OAuthConsumerKey + "&Nonce=" + MirNonce + "<launchUrl>";
        // rsp += "<launchResponse>\n";
        // rsp += "<status>success</status>\n";
        // rsp += "<type>iframe</type>\n";
        // rsp += "<launchUrl>" + Utility.GetSiteRoot() + "/Course/Nav.aspx?FN=" + OAuthConsumerKey + "&Nonce=" + MirNonce + "</launchUrl>";
        // rsp += "</launchResponse>\n";

        Response.Clear();
        Response.Write(rsp);
        //Response.Redirect("~/Course/Nav.aspx?FN=" + OAuthConsumerKey + "&Nonce=" + MirNonce);
    }

    private void SimpleLTI()
    {
        if (ValidateNonce())
        {
            LMSData.UserController uc = new LMSData.UserController();
            LMSData.UserProfileController upc = new LMSData.UserProfileController();
            LMSData.User usr = uc.FetchByName(Email);
            if (!usr.IsLoaded)
            {
                System.Web.Security.Membership.CreateUser(Email, Guid.NewGuid().ToString(), Email);
                usr = uc.FetchByName(Email);
                LMSData.UserProfile up = upc.FetchByUserID(usr.UserID);
                up.UserID = usr.UserID;
                up.FirstName = FirstName;
                up.LastName = LastName;
                up.Save();
            }
            string rsp = "";
            rsp += "<launchResponse>\n";
            rsp += "<status>success</status>\n";
            rsp += "<type>iframe</type>\n";
            //if (ToolID.ToLower().Contains("course"))
            //    rsp += "<launchUrl>" + Utility.GetSiteRoot() + "/Course/QuickLMSNav.aspx?FN=" + ToolID.ToLower().Replace("course=", "") + "</launchUrl>\n";
            //else if (ToolID.ToLower().Contains("asmt"))
            //    rsp += "<launchUrl>" + Utility.GetSiteRoot() + "/Course/Report.aspx?Aid=" + ToolID.ToLower().Replace("asmt=", "") + "</launchUrl>\n";
            rsp += "<launchUrl>" + Utility.GetSiteRoot() + "/Course/Nav.aspx?FN=" + CourseID + "&amp;islti=1</launchUrl>\n";
            rsp += "</launchResponse>\n";
            if (Action != "launchresolve")
                Response.Redirect("~/Course/Nav.aspx?FN=" + ToolID + "&islti=1");
            Response.Clear();
            Response.Write(rsp);
        }
        else
        {
            string rsp = "";
            rsp += "<launchResponse>\n";
            rsp += "<status>success</status>\n";
            rsp += "<type>iframe</type>\n";
            rsp += "<launchUrl>" + Utility.GetSiteRoot() + "/AuthenticateFail.aspx?msg=Security%20digest%20did%20not%20authenticate.%20%20Please%20check%20package%20and%20launch%20parameters%20then%20try%20again.</launchUrl>";
            rsp += "</launchResponse>\n";
            Response.Clear();
            Response.Write(rsp);
        }
    }

    private bool ValidateNonce()
    {
        string presha1 = Nonce + DateStamp + Secret;
        string sha1 = "";

        try
        {
            UTF8Encoding encoding = new UTF8Encoding();
            byte[] hashBytes = encoding.GetBytes(presha1);

            // compute SHA-1 hash.
            SHA1 md = new SHA1CryptoServiceProvider();
            byte[] cryptstr = md.ComputeHash(hashBytes);

            try
            {
                sha1 = Convert.ToBase64String(cryptstr);
            }
            catch (Exception e)
            {
                throw new Exception("Error in base64Encode" + e.Message);
            }
        }
        catch (NotSupportedException)
        {
        }

        if (sha1 != Digest)
            return false;
        return true;
    }
}
